
/**
 * AppleIIGo
 * Motherboard class
 * (C) 2007-2008 by Marc S. Ressl (mressl@umich.edu)
 * Released under the GPL
 */

#ifndef MOTHERBOARD_H
#define MOTHERBOARD_H

#define APPLEIIGO_VERSION "2.0"
#define APPLEIIGO_BUILD "307"

#include "types.h"
#include "bitMacros.h"
#include "List.h"
#include "Device.h"
#include "Interrupt.h"
#include "Resources.h"

#include "CPU.h"
#include "MMU.h"
#include "IOU.h"
#include "Memory.h"
#include "MIG.h"
#include "TimingGenerator.h"
#include "VideoRenderer.h"
#include "Speaker.h"
#include "Keyboard.h"
#include "Paddles.h"
#include "Mouse.h"
#include "ADB.h"
#include "DOC.h"
#include "RTC.h"
#include "SCC.h"

#include "SlotDevice.h"
#include "AuxSlotDevice.h"
#include "ChipDevice.h"

#include "DiskDrive.h"

struct MotherboardConfigurationType {
	char * configurationName;
	UINT32 cpuType;
	UINT32 mmuType;
	UINT32 iouType;
	UINT32 mainMemoryType;
	UINT32 mainMemoryByteNum;
	char * romImage;
	UINT32 romByteNum;
	UINT32 romBank1Index;
	UINT32 isPalTiming;
	UINT32 videoType;
	UINT32 videoRendererType;
	UINT32 characterSetType;
	char * characterSetRomImage;
	UINT32 speakerType;
	bool isKeyboardLowerCase;
	char * internalSlotDeviceType[MAPPEDSLOT_NUM];
	char * chipDeviceType;
};

class Motherboard {
public:
	Motherboard(char * profilePath, char * resourcesPath);
	~Motherboard();
	
	void reset();
	void restart();
	
	SINT32 * getAudioInputBuffer();
	SINT32 * getAudioOutputBuffer();
	UINT32 processFrame();
	
	void registerDevice(class Device * device);
	
	void registerDiskDrive(class DiskDrive * diskDrive);
	bool mount(char * diskImagePath, UINT32 diskDriveIndex);
	void unmount(UINT32 mountIndex);
	
	void onResetAsserted(bool isRestart);
	void onResetCleared();
	
	class Resources * getResources();
	
	void setCpu(class CPU * cpu);
	class CPU * getCpu();
	class MMU * getMmu();
	class IOU * getIou();
	class Memory * getMemory();
	class MIG * getMig();
	class TimingGenerator * getTimingGenerator();
	class VideoRenderer * getVideoRenderer();
	class Speaker * getSpeaker();
	class Keyboard * getKeyboard();
	class Paddles * getPaddles();
	class Mouse * getMouse();
	class ADB * getAdb();
	class DOC * getDoc();
	class RTC * getRtc();
	class SCC * getSccA();
	class SCC * getSccB();
	class AuxSlotDevice * getAuxSlotDevice();
	class SlotDevice * getSlotDevice(UINT32 slotIndex);
	class ChipDevice * getChipDevice();
	
private:
	class List * deviceList;
	class List * diskDriveList;
	
	class Resources * resources;
	
	class CPU * cpu;
	class CPU * motherboardCpu;
	class MMU * mmu;
	class IOU * iou;
	class Memory * memory;
	class MIG * mig;
	class TimingGenerator * timingGenerator;
	class VideoRenderer * videoRenderer;
	class Speaker * speaker;
	class Keyboard * keyboard;
	class Paddles * paddles;
	class Mouse * mouse;
	class ADB * adb;
	class DOC * doc;
	class RTC * rtc;
	class SCC * sccA;
	class SCC * sccB;
	class SlotDevice * slot[SLOT_END];
	class AuxSlotDevice * auxSlot;
	class ChipDevice * chip;
	
	struct MotherboardConfigurationType * getConfiguration(char * confName);
	void reconnect();
	void requestMemory();
};

#endif
